package test.flow;

import java.util.Map;

import hyl.base.flow.chart.CNodeNet;
import hyl.base.flow.chart.CThrough;
import hyl.base.flow.chart.CWorkOrd;
import hyl.base.flow.chart.CWorkOrdDb;
import hyl.base.flow.chart.INode;
import hyl.base.flow.chart.IWorkOrd;
import hyl.base.flow.chart.IWorker;
import hyl.core.MyDate;
import hyl.core.MyFun;
import hyl.core.data.CcMap;
import hyl.core.data.IMap;

public class demo {
	public static void main(String[] args) {
		 testwhile();
		//testdb();
		// testChart();
		// testThrough();

	}

	static void test() {
		Map<String, Object> mp = new CcMap<String, Object>();
		mp.put("dd", "vv");
		@SuppressWarnings("unchecked")
		IMap<String, Object> mmp = (IMap<String, Object>) mp;
		MyFun.printJson(mmp);
	}

	static String print(INode 当前节点, IWorkOrd 工单, Object... objs) {
		String string = MyFun.join2(" ", 工单.getId(), 当前节点.getId(), 工单.toJsonString());
		System.out.println(string);
		return "Y";
	}

	// 测试 可以持久化的工单
	public static void testdb() {
		CNodeNet 链路图 = new CNodeNet();
		链路图.add链路组("A>B>C");
		IWorker w_a = (node, 工单, objs) -> {
			if (!工单.hasAttr("aa"))
				工单.putAttr("aa", new Object[] {1,"23","下次V下"});
			// int i=(int)工单.getAttr("aa");
			// MyFun.print(i+1);
			return print(node, 工单);
		};

		class Workb implements IWorker {
			@Override
			public Object run(INode 当前节点, IWorkOrd 工单, Object... objs) throws Exception {
				MyDate.sleeps(1);
				//MyFun.print(工单.getAttrInt("aa"));
				return print(当前节点, 工单);
			}
		}

		IWorker w_c = (node, 工单, objs) -> {
			MyDate.sleeps(1);
			//MyFun.print(工单.getAttrInt("aa"));
			return print(node, 工单);
		};
		链路图.setWorks("A,B,C", new IWorker[] { w_a, new Workb(), w_c });

		CWorkOrdDb workOrd = new CWorkOrdDb();

		链路图.down("A", workOrd);
		workOrd.closeDb();
	}

	/**
	 * 演示循环多次处理 初始化d=2 让f循环2次
	 * 
	 */
	public static void testwhile() {
		CNodeNet 链路图 = new CNodeNet();
		链路图.add链路组("A>B>C>F>H", "F>D>B");
		IWorker w_a = (node, 工单, objs) -> {
			if (!工单.hasAttr("a"))
				工单.putAttr("a", 100);
			return print(node, 工单);
		};

		class Workb implements IWorker {
			@Override
			public Object run(INode 当前节点, IWorkOrd 工单, Object... objs) throws Exception {
				if (!工单.hasAttr("c"))
					工单.putAttr("c", 3);
				return print(当前节点, 工单);
			}
		}

		IWorker w_c = (node, 工单, objs) -> {
			return print(node, 工单);
		};

		IWorker w_d = (node, 工单, objs) -> {
			工单.decAttr("c");
			if (工单.getAttrInt("c") < 0)
				return null;
			return print(node, 工单);
		};
		IWorker w_f = (node, 工单, objs) -> {
			if (!工单.hasAttrs("a", "c"))
				return null;

			if (!工单.hasAttr("f"))
				工单.putAttr("f", 工单.getAttrInt("a"));
			if (工单.getAttrInt("c") > 0) {
				int i = 工单.getAttrInt("f");
				工单.putAttr("f", i + 10);
			}
			return print(node, 工单);
		};
		IWorker w_h = (node, 工单, objs) -> {
			if (工单.getAttrInt("c") > 0)
				return null;
			return print(node, 工单);
		};
		链路图.setWorks("A,B,C,D,F,H", new IWorker[] { w_a, new Workb(), w_c, w_d, w_f, w_h });

		CWorkOrd workOrd = new CWorkOrd();

		链路图.down("A", workOrd);

	}

	/**
	 * 例子:普通串行图 支持高并发处理,没有采用阻塞设计,而采用条件属性限定工作是否可以执行
	 * 
	 * 演示了流的分支与合并
	 */
	public static void testChart() {
		CNodeNet 链路图 = new CNodeNet();
		链路图.add链路组("A>B>C>F>H>K", "B>E>F", "B>D>F");

		IWorker w_a = (node, 工单, objs) -> {

			int i = MyFun.obj2Int(工单.getAttr("ini"));
			工单.putAttr("a", i * 10);
			工单.delAttr("ini");
			return print(node, 工单);
		};

		class Workb implements IWorker {
			@Override
			public Object run(INode 当前节点, IWorkOrd 工单, Object... objs) throws Exception {
				int i = MyFun.obj2Int(工单.getAttr("a"));

				工单.putAttr("c", (int) (i * 0.1));
				工单.putAttr("d", (int) (i * 0.6));
				工单.putAttr("e", (int) (i * 0.3));
				return print(当前节点, 工单);
			}
		}

		IWorker w_c = (node, 工单, objs) -> {

			int i = MyFun.obj2Int(工单.getAttr("c"));
			工单.putAttr("c", i * 3);
			return print(node, 工单);

		};

		IWorker w_d = (node, 工单, objs) -> {

			int i = MyFun.obj2Int(工单.getAttr("d"));
			工单.putAttr("d", i * 1);
			return print(node, 工单);
		};

		IWorker w_e = (node, 工单, objs) -> {

			int i = MyFun.obj2Int(工单.getAttr("e"));
			工单.putAttr("e", i * 2);
			return print(node, 工单);

		};
		IWorker w_f = (node, 工单, objs) -> {
			int i1 = MyFun.obj2Int(工单.getAttr("c"));
			int i2 = MyFun.obj2Int(工单.getAttr("d"));
			int i3 = MyFun.obj2Int(工单.getAttr("e"));
			if (!工单.hasAttrs("c", "d", "e"))
				return null;
			// 加工过就不可以再遍历
			if (工单.hasAttr("f"))
				return null;
			// MyFun.print( i1 , i2 , i3);
			工单.putAttr("f", i1 + i2 + i3);
			return print(node, 工单);

		};

		IWorker w_ = (node, 工单, objs) -> {
			return print(node, 工单);
		};
		链路图.setWorks("A,B,C,D,E,F", new IWorker[] { w_a, new Workb(), w_c, w_d, w_e, w_f });
		链路图.setWork("H,K,I,L", w_);

		CWorkOrd workOrd = new CWorkOrd();
		workOrd.putAttr("ini", 10);
		链路图.down("A", workOrd);
		CWorkOrd workOrd2 = new CWorkOrd();
		workOrd2.putAttr("ini", 20);
		链路图.down("A", workOrd2);

	}

	public static void testThrough() {
		// 测试遍历引擎
		// String s = "初始字符串";
		class work implements IWorker {
			@Override
			public Object run(INode 当前节点, IWorkOrd 工单, Object... 其他参数) throws Exception {
				String string = MyFun.join(当前节点.getId(), " ", 工单);
				System.out.println(string);
				return string;
			}
		}
		;
		CThrough through = new CThrough();
		through.addWork(new work());
		CNodeNet 链路图 = new CNodeNet();
		链路图.add链路组("A>B>C>F>H");
		try {
			through.througUp(链路图.get节点("H"));
		} catch (Exception e) {
			e.printStackTrace();
		}
		try {
			through.througDown(链路图.get节点("A"));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
